package com.beyondsoft.mcms.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.security.access.prepost.PreAuthorize;

import com.beyondsoft.mcms.common.CommonUtils;
import com.beyondsoft.mcms.common.Constants;
import com.beyondsoft.mcms.domain.Advice;
import com.beyondsoft.mcms.domain.Conference;
import com.beyondsoft.mcms.domain.GroupInfo;
import com.beyondsoft.mcms.domain.Item;
import com.beyondsoft.mcms.domain.MemberInfo;
import com.beyondsoft.mcms.domain.Users;
import com.beyondsoft.mcms.reference.AuthRole;

public class MemberInfoServiceImpl implements MemberInfoService {

	@PreAuthorize("isAuthenticated() AND (hasRole('ADMIN'))")
	public void saveMemberInfo(MemberInfo memberInfo) {

		Users users = new Users();
		users.setUsername(memberInfo.getUsername());
		users.setEnabled(true);
		users.setCreateDate(new Date());
		users.setCreatedBy(CommonUtils.getCurrentUsername());

		Long positionId = memberInfo.getPositionType().getId();
		if (positionId.equals(Constants.POSITION_PRE)) {
			users.setAuthority(AuthRole.PREUSER);
		} else {
			users.setAuthority(AuthRole.ORDINARY);
		}

		String pwd = memberInfo.getPassword();
		if (pwd != null && pwd.length() > 0) {
			users.setPassword(CommonUtils.encodingPWD(pwd));
			memberInfo.setPassword(null);
		} else {
			users.setPassword(CommonUtils.encodingPWD(users.getUsername()));
		}

		users.persist();
		memberInfo.persist();
	}

	@PreAuthorize("isAuthenticated() AND (hasRole('ADMIN'))")
	public MemberInfo updateMemberInfo(MemberInfo memberInfo) {

		MemberInfo oldMemberInfo = MemberInfo.findMemberInfo(memberInfo.getId());
		Long positionId = memberInfo.getPositionType().getId();
		Long oldPositionId = oldMemberInfo.getPositionType().getId();

		if (!positionId.equals(oldPositionId)) {
			Users user = Users.findUsersesByUsernameEquals(memberInfo.getUsername()).getSingleResult();

			if (oldPositionId.equals(Constants.POSITION_PRE)) {
				user.setAuthority(AuthRole.ORDINARY);
				user.merge();
			} else if (positionId.equals(Constants.POSITION_PRE)) {
				user.setAuthority(AuthRole.PREUSER);
				user.merge();
			}
		}

		return memberInfo.merge();
	}

	@PreAuthorize("isAuthenticated() AND (hasRole('ADMIN'))")
	public void deleteMemberInfo(MemberInfo memberInfo) {
		Users user = Users.findUsersesByUsernameEquals(memberInfo.getUsername()).getSingleResult();
		user.remove();
		memberInfo.remove();
	}

	@PreAuthorize("isAuthenticated() AND (hasRole('ADMIN'))")
	public void generateConferenceAdvices(Conference conference, List<MemberInfo> memberinfoes) {

		MemberInfo memberInfo = null;
		for (Iterator<MemberInfo> it = memberinfoes.iterator(); it.hasNext();) {
			memberInfo = (MemberInfo) it.next();
			Advice advice = new Advice();
			advice.setCreateDate(new Date());
			advice.setCreatedBy(CommonUtils.getCurrentUsername());
			advice.setConference(conference);
			advice.setMemberInfo(memberInfo);
			advice.persist();
		}
		conference.setConferenceStatus(Item.findItem(Constants.CONFERENCE_STATUS_REGISTERING));
		conference.merge();

	}

	@Override
	public List<MemberInfo> findMemberInfoByGroupInfo(GroupInfo groupInfo) {
		Set<Item> businesstypes = groupInfo.getBusinessTypes();
		Set<Item> positiontypes = groupInfo.getPositionTypes();

		List<Long> businessIds = new ArrayList<Long>(), positionTypeIds = new ArrayList<Long>();
		for (Iterator<Item> it = businesstypes.iterator(); it.hasNext();) {
			Item item = (Item) it.next();
			if (item.getIsValid()) {
				businessIds.add(item.getId());
			}
		}
		for (Iterator<Item> it = positiontypes.iterator(); it.hasNext();) {
			Item item = (Item) it.next();
			if (item.getIsValid()) {
				positionTypeIds.add(item.getId());
			}
		}
		List<MemberInfo> memberinfoList = new ArrayList<MemberInfo>();
		if (businesstypes.size() == 0 && positionTypeIds.size() == 0) {
			memberinfoList = MemberInfo.findAllMemberInfoes();
		} else {
			memberinfoList = MemberInfo.findMemberInfoesByBusinessTypeInAndPositionTypeIn(businessIds, positionTypeIds)
					.getResultList();
		}
		return memberinfoList;
	}

}
